import 'package:cloud_music/ui/widgets/net_error_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';

// 可以用 enhanced_future_builder 插件

//builder的参数为 Widget Function()
typedef ValueWidgetBuilder<T> = Widget Function(BuildContext context, T value);

// FutureBuilder 简单封装，除正确返回和错误外，其他返回 加载状态
// 错误时返回定义好的错误 Widget，例如点击重新请求

class QFutureBuilder<T> extends StatefulWidget {
  // Widget的builder参数
  final ValueWidgetBuilder<T> builder;
  // 数据请求函数
  final Function futureFunc;
  // 参数
  final Map<String, dynamic> params;
  final Widget loadingWidget;

  QFutureBuilder(
      {Key key,
      @required this.builder,
      @required this.futureFunc,
      this.params,
      Widget loadingWidget})
      // 初始化参数, 跟cpp一样
      : loadingWidget = loadingWidget ?? _buildLoading(),
        super(key: key);

  @override
  _QFutureBuilderState<T> createState() => _QFutureBuilderState<T>();

  static Widget _buildLoading() {
    return Container(
      alignment: Alignment.center,
      height: ScreenUtil().setWidth(200),
      child: CupertinoActivityIndicator(),
    );
  }
}

class _QFutureBuilderState<T> extends State<QFutureBuilder> {
  Future<T> _future;
  String oldParams = '';

  @override
  void initState() {
    super.initState();
    // 第一帧 初始化一下context, 参考 https://blog.csdn.net/qq_23756803/article/details/102384092
    WidgetsBinding.instance.addPostFrameCallback((_) {
      _request();
    });
  }

  void _request() {
    setState(() {
      if (widget.params == null) {
        _future = widget.futureFunc(context);
      } else {
        _future = widget.futureFunc(context, params: widget.params);
        oldParams = widget.params.values.join();
      }
    });
  }

  // 默认 两次Future不一样就会重建,重写此方法,自定义控件重建时机
  @override
  void didUpdateWidget(QFutureBuilder oldWidget) {
    // 两次 Future 不一样的情况下会重新走一遍流程, 重新请求
    if (oldWidget.futureFunc != widget.futureFunc) {
      WidgetsBinding.instance.addPostFrameCallback((_) {
        _request();
      });
    } else if (oldWidget.params != null &&
        widget.params != null &&
        oldParams != widget.params.values.join()) {
      // 如果方法一样,参数不一样也重新请求
      oldParams = widget.params.values.join();
      WidgetsBinding.instance.addPostFrameCallback((call) {
        _request();
      });
    }

    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    return _future == null
        ? widget.loadingWidget
        : FutureBuilder(
            future: _future,
            builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
              switch (snapshot.connectionState) {
                case ConnectionState.none:
                case ConnectionState.waiting:
                case ConnectionState.active:
                  return widget.loadingWidget;
                case ConnectionState.done:
                  if (snapshot.hasData) {
                    return widget.builder(context, snapshot.data);
                  } else if (snapshot.hasError) {
                    return NetErrorWidget(callback: () => _request());
                  }
              }
              return Container();
            });
  }
}
